/**
 * BOM信息发布类
 * 
 * @author 魏文杰 
 * @Version 1.0
 * @Date 2013-10-08
 */

package ext.generic.erp.service;

import java.util.ArrayList;
import java.util.List;

import ext.com.core.CoreUtil;
import ext.generic.erp.common.CommonPDMUtil;
import ext.generic.erp.rule.BussinessRule;
import ext.generic.erp.task.BomStructureIETask;
import ext.generic.erp.task.BomInfoIETask;
import ext.generic.erp.task.BomStructureRemoveByParentIETask;
import ext.generic.erp.util.BOMStructureUtil;
import ext.generic.erp.util.BusinessRuleXMLConfigUtil;
import ext.generic.erp.util.IntegrationConstant;
import ext.generic.erp.util.PDMIntegrationLogUtil;
import ext.tianma.part.resolution.UpdateIBAForChildPart;
import wt.change2.WTChangeOrder2;
import wt.fc.Persistable;
import wt.fc.collections.WTArrayList;
import wt.part.WTPart;
import wt.part.WTPartMaster;
import wt.part.WTPartUsageLink;
import wt.util.WTException;

public class BOMReleaseService {	
	private static boolean verbose = PDMIntegrationLogUtil.verbose ;

	private static String clazz = BOMReleaseService.class.getName() ;
	
	/**
	 * 发布PBO单层BOM结构，如果不是WTPart，则不处理
	 * 
	 * @param obj
	 */
	public static void releaseSingleLevel( Object obj ){
		releaseSingleLevel( obj , "" , null ) ;
	}
	
	/**
	 * 发布PBO单层BOM结构，如果不是WTPart，则不处理
	 * 如果不在ECN中，则WTChangeOrder2 ecn设置为null
	 * 
	 * @param obj
	 * @param releaseTime
	 * @param ecn
	 */
	public static void releaseSingleLevel( Object obj , String releaseTime, WTChangeOrder2 ecn ){
		if(obj != null && obj instanceof WTPart){
			WTPart part = ( WTPart ) obj ;
			releaseSingleLevel( part , "" , ecn) ;
		}
	}
	
	/**
	 * 发布WTPart单层BOM结构
	 * 
	 * @param part
	 */
	public static void releaseSingleLevel( WTPart part ){
		releaseSingleLevel( part , "" , null) ;
	}
	
	/**
	 * 发布WTPart单层BOM结构
	 * 如果不在ECN中，则WTChangeOrder2 ecn设置为null
	 * 
	 * @param part
	 * @param releaseTime
	 * @param ecn
	 */
	public static void releaseSingleLevel( WTPart part , String releaseTime, WTChangeOrder2 ecn ){
		if( part == null ){
			return ;
		}
		
		String ecnNumber = "" ;
		
		if(ecn != null){
			ecnNumber = ecn.getNumber() ;
		}
		
		try{
			//获取同一视图下最新版本的零部件
			part = CoreUtil.getWTPartByNumberAndView(part.getNumber(), part.getViewName()) ;
			
			//发布ECN信息到中间表。
			ECNReleaseService.release( ecn , releaseTime) ;
			
			//发布父件物料信息
			PartReleaseService.release(part, releaseTime) ;
			
			//发布第一层子件和子件关联关系
			releaseFirstLevel(part, releaseTime , ecnNumber) ;
		} catch (WTException e) {
			e.printStackTrace();
		}finally{
			
		}
	}
	
	/**
	 * 发布List列表中的所有零部件的单层BOM结构
	 * 
	 * @param parts
	 */
	public static void releaseSingleLevel(List<WTPart> parts){
		if( parts == null ){
			return ;
		}
		
		int size = parts.size() ;
		
		for( int i=0 ; i<size ; i++ ){
			WTPart part = parts.get(i) ;
			
			releaseSingleLevel( part ) ;
		}
	}
	
	/**
	 * 发布List列表中的所有零部件的单层BOM结构
	 * 如果不在ECN中，则WTChangeOrder2 ecn设置为null
	 * 
	 * @param parts
	 * @param releaseTime
	 * @param ecn
	 */
	public static void releaseSingleLevel(List<WTPart> parts , String releaseTime, WTChangeOrder2 ecn ){
		if( parts == null ){
			return ;
		}
		
		int size = parts.size() ;
		
		for( int i=0 ; i<size ; i++ ){
			WTPart part = parts.get(i) ;
			
			releaseSingleLevel( part , releaseTime, ecn ) ;
		}
	}
	
	/**
	 * 发布WTArrayList列表中的所有零部件的单层BOM结构
	 * 
	 * @param parts
	 */
	public static void releasePersistableSingleLevel( WTArrayList parts ){
		releasePersistableSingleLevel( parts , "" ,  null ) ;
	}
	
	/**
	 * 发布WTArrayList列表中的所有零部件的单层BOM结构
	 * 如果不在ECN中，则WTChangeOrder2 ecn设置为null
	 * 
	 * @param parts
	 * @param releaseTime
	 * @param ecn
	 */
	public static void releasePersistableSingleLevel( WTArrayList parts , String releaseTime, WTChangeOrder2 ecn ){
		if( parts == null ){
			return ;
		}
		
		try{
			
			int size = parts.size() ;
			
			for( int i=0 ; i<size ; i++ ){
				Persistable persistable = parts.getPersistable(i) ;
				
				if( persistable != null && persistable instanceof WTPart ){
					WTPart part = ( WTPart ) persistable ;
					
					releaseSingleLevel( part , releaseTime, ecn ) ;
				}
			}
		} catch (WTException e) {
			e.printStackTrace();
		}finally{
			
		}
	}
	
	/**
	 * 发布PBO的所有BOM结构
	 * 
	 * @param obj
	 */
	public static void releaseAllLevel( Object obj ){
		releaseAllLevel( obj , "" , null ) ;
	}
	
	/**
	 * 发布PBO的所有BOM结构
	 * 如果不在ECN中，则WTChangeOrder2 ecn设置为null
	 * 
	 * @param obj
	 * @param releaseTime
	 * @param ecn
	 */
	public static void releaseAllLevel( Object obj , String releaseTime, WTChangeOrder2 ecn ){
		if(obj != null && obj instanceof WTPart){
			WTPart part = ( WTPart ) obj ;
			releaseAllLevel( part , "" , ecn) ;
		}
	}
	
	/**
	 * 发布WTPart的所有BOM结构
	 * 
	 * @param part
	 */
	public static void releaseAllLevel( WTPart part ){
		releaseAllLevel(part , "" , null) ;
	}
	
	/**
	 * 发布WTPart的所有BOM结构
	 * 如果不在ECN中，则WTChangeOrder2 ecn设置为null
	 * 
	 * @param part
	 * @param releaseTime
	 * @param ecn
	 */
	public static void releaseAllLevel( WTPart part , String releaseTime, WTChangeOrder2 ecn ){
		System.out.println("=====>>>start  同步ibaVlaue<<<<=====");
		UpdateIBAForChildPart.getPartIBAForPPart(part);
		System.out.println("=====>>>end  同步ibaVlaue<<<<=====");
		if( part == null ){
			return ;
		}
		
		String ecnNumber = "" ;
		
		if( ecn != null ){
			ecnNumber = ecn.getNumber() ;
		}
		
		if( ecnNumber == null ){
			ecnNumber = "" ;
		}
		
		//获取同一视图下最新版本的零部件
		try {
			part = CoreUtil.getWTPartByNumberAndView(part.getNumber(), part.getViewName()) ;
		} catch (WTException e) {
			e.printStackTrace();
		}
		
		//发布ECN信息到中间表。
		ECNReleaseService.release( ecn , releaseTime) ;
		
		//发布根节点物料信息
		PartReleaseService.release( part , releaseTime) ;
		
		List<WTPart> childList = releaseFirstLevel( part , releaseTime , ecnNumber ) ;
		
		//必须判断size，否则会导致死循环
		while( ( childList != null ) && ( childList.size() > 0 ) ){
			List<WTPart> tempList = new ArrayList<WTPart>() ;
			tempList.clear();
			
			int childListSize = childList.size() ;
			
			for(int i=0 ; i < childListSize ; i++ ){
				WTPart childPart = childList.get(i) ;
				
				List<WTPart> tempChildList = releaseFirstLevel( childPart , releaseTime , ecnNumber) ;
				
				tempList.addAll(tempChildList) ;
			}
			
			childList = tempList ;
		}
	}
	
	/**
	 * 发布List列表中WTPart的所有BOM结构
	 * 
	 * @param parts
	 */
	public static void releaseAllLevel(List<WTPart> parts){
		releaseAllLevel( parts , "" , null ) ;
	}
	
	/**
	 * 发布List列表中WTPart的所有BOM结构
	 * 如果不在ECN中，则WTChangeOrder2 ecn设置为null
	 * 
	 * @param parts
	 * @param releaseTime
	 * @param ecn
	 */
	public static void releaseAllLevel(List<WTPart> parts , String releaseTime , WTChangeOrder2 ecn ){
		if( parts == null ){
			return ;
		}
		
		int size = parts.size() ;
		
		for(int i=0 ; i<size ; i++ ){
			WTPart part = parts.get(i) ;
			
			releaseAllLevel( part , releaseTime, ecn ) ;
		}
	}
	
	/**
	 * 发布WTArrayList列表中WTPart的所有BOM结构
	 * 
	 * @param parts
	 */
	public static void releasePersistableAllLevel( WTArrayList parts ){
		releasePersistableAllLevel( parts , "" , null ) ;
	}
	
	/**
	 * 发布WTArrayList列表中WTPart的所有BOM结构
	 * 如果不在ECN中，则WTChangeOrder2 ecn设置为null
	 * 
	 * @param parts
	 * @param releaseTime
	 * @param ecn
	 */
	public static void releasePersistableAllLevel( WTArrayList parts , String releaseTime, WTChangeOrder2 ecn ){
		if( parts == null ){
			return ;
		}
		
		try{
			
			int size = parts.size() ;
			
			for( int i=0 ; i<size ; i++ ){
				Persistable persistable = parts.getPersistable(i) ;
				
				if( persistable != null && persistable instanceof WTPart ){
					WTPart part = ( WTPart ) persistable ;
					
					releaseAllLevel( part , releaseTime, ecn ) ;
				}
			}
		} catch (WTException e) {
			e.printStackTrace();
		}finally{
			
		}
	}
	
	/**
	 * 发布单层BOM结构
	 * 
	 * @param part
	 * @param releaseTime
	 * @param ecnNumber
	 * @return
	 */
	private static List<WTPart> releaseFirstLevel( WTPart part , String releaseTime , String ecnNumber ){		
		List<WTPart> list = new ArrayList<WTPart>() ;
		if( part == null ){
			return list ;
		}
		
		//如果part为特殊的部件类型，不需要做集成，则此Part的BOM结构也不做集成
		boolean canRelease = BussinessRule.canReleasePart(part) ;
		if( ! canRelease ){
			if( verbose ){
				PDMIntegrationLogUtil.printLog(clazz, notReleaseBOMLogInfo(part)  , IntegrationConstant.LOG_LEVEL_WARN) ;
			}
			
			return list ;
		}
		
		try {
			if( verbose ){
				PDMIntegrationLogUtil.printLog(clazz, startReleaseBOMLogInfo(part)  , IntegrationConstant.LOG_LEVEL_INFO) ;
			}
			
			//发布子件物料信息
			list = BOMStructureUtil.getFirstLevelChildren(part) ;
			
			PartReleaseService.release( list , releaseTime) ;

			//先删除之前已经发布的同一大版本的usageLink记录，保证中间数据库中，同一时间，只存在一个大版本的记录
			BomStructureRemoveByParentIETask.delete(part) ;
			
			//发布父子件关联关系
			List<WTPartUsageLink> usageLinkList = BOMStructureUtil.getFirstLevelUsageLink(part) ;
			int size = usageLinkList.size() ;
			
			if( verbose ){
				PDMIntegrationLogUtil.printLog(clazz, "获取结构关系数量为：" + size , IntegrationConstant.LOG_LEVEL_INFO) ;
			}
			
			for( int i = 0 ; i < size ; i++ ){
				WTPartUsageLink usageLink = usageLinkList.get(i) ;
				
				if(verbose){
					PDMIntegrationLogUtil.printLog(clazz, "发布BOM结构信息:\n" + CommonPDMUtil.getWTPartUsageLinkInfo(usageLink)  , IntegrationConstant.LOG_LEVEL_INFO) ;
				}
				
				//获取子件
				WTPartMaster  childMaster = usageLink.getUses() ;
				WTPart childPart = CoreUtil.getWTPartByMasterAndView(childMaster, part.getViewName()) ;
				
				//判断子件是否为可发布类型
				if( BussinessRule.canReleasePart( childPart ) ){
					BomStructureIETask.add(usageLink, releaseTime) ;
					
					//发布特定替代关系
					ReplacementReleaseService.releaseSubstitute( usageLink , releaseTime ) ;
					
					//发布全局替代关系
					if( BussinessRule.isAlternateLinkRelease() ){
						ReplacementReleaseService.releaseAlternate( usageLink.getUses() , releaseTime ) ;
					}
				}
			}
			
			//如果有子件，则将当前父件发布到BOM Root Info表中
			if( size > 0 ){
				//发布父节点信息，表示当前层的结构已经发布完毕
				BomInfoIETask.add(part, releaseTime, ecnNumber) ;
				
				if( verbose ){
					PDMIntegrationLogUtil.printLog(clazz, finishReleaseBOMLogInfo(part)  , IntegrationConstant.LOG_LEVEL_INFO) ;
				}
			}
			
			//如果当前层的BOM结构已经成功发布，则更新系统的BOM发布状态
			boolean hasBom = BomInfoIETask.hasObject(part) ;
			if( hasBom ){
				UpdatePDMDataService.updatePDMSucessful( part , BusinessRuleXMLConfigUtil.getInstance().getBomReleaseStatus() );
			}else{
				UpdatePDMDataService.updatePDMFailed( part , BusinessRuleXMLConfigUtil.getInstance().getBomReleaseStatus() );
			}
		} catch (Exception e) {
			if( verbose ){
				PDMIntegrationLogUtil.printLog(clazz, failedReleaseBOMLogInfo(part)  , IntegrationConstant.LOG_LEVEL_ERROR ) ;
				PDMIntegrationLogUtil.printLog(clazz, e.getMessage() , IntegrationConstant.LOG_LEVEL_ERROR ) ;
			}
			
			e.printStackTrace();
		}
		
		return list ;
	}
	
	private static String startReleaseBOMLogInfo(WTPart part){
		String logInfo = "开始发布零部件BOM结构信息到ERP：\n" ;
		logInfo = logInfo + CommonPDMUtil.getPartInfo( part );
		return logInfo ;
	}
	
	private static String finishReleaseBOMLogInfo(WTPart part){
		String logInfo = "成功发布零部件BOM结构信息到ERP：\n" ;
		logInfo = logInfo + CommonPDMUtil.getPartInfo( part );
		return logInfo ;
	}
	
	private static String failedReleaseBOMLogInfo(WTPart part){
		String logInfo = "发布零部件BOM结构信息到ERP失败：\n" ;
		logInfo = logInfo + CommonPDMUtil.getPartInfo( part );
		return logInfo ;
	}
	
	private static String notReleaseBOMLogInfo(WTPart part){
		String logInfo = "零部件BOM结构信息不发布到ERP：\n" ;
		logInfo = logInfo + CommonPDMUtil.getPartInfo( part );
		return logInfo ;
	}
}
